# encoding: utf-8
# @File  : ai_optimizer.py
# @Author: shaoyun
# @Date  :  2025/05/11
from loguru import logger
from datetime import datetime
from typing import Dict, List, Optional, Any, Tuple
import json
from openai import OpenAI

from app.core.config import settings
from app.db.mongo_manager import MongoDB


class AIOptimizer:
    """AI优化器 - 集成DeepSeek API进行任务优化和异常检测"""

    def __init__(self):
        """初始化OpenAI客户端"""
        if settings.DEEPSEEK_API_KEY:
            self.client = OpenAI(
                api_key=settings.DEEPSEEK_API_KEY,
                base_url=settings.DEEPSEEK_BASE_URL
            )
            logger.info("Deepseek客户端初始化成功！！！")
        else:
            self.client = None
            logger.warning("DeepSeek API key not configured")

    @staticmethod
    async def _get_historical_data(spider_id: str) -> Dict[str, Any]:
        """获取历史任务数据"""
        # 这里需要实现从数据库获取历史数据的逻辑
        # 暂时返回示例数据
        return {
            'avg_execution_time': 30.5,
            'success_rate': 95.2,
            'failure_count': 3
        }

    @staticmethod
    async def _collect_performance_data(time_range: str) -> Dict[str, Any]:
        """收集系统性能数据"""
        # 这里需要实现从监控系统收集性能数据的逻辑
        # 暂时返回示例数据
        return {
            'total_tasks': 1000,
            'success_tasks': 950,
            'failed_tasks': 50,
            'avg_execution_time': 45.2,
            'node_count': 5,
            'active_nodes': 4
        }

    async def predict_task_priority(
            self,
            task_id: str,
            spider_id: str,
            parameters: Optional[Dict[str, Any]] = None
    ) -> int:
        """预测任务优先级"""
        try:
            if not self.client:
                logger.warning("DeepSeek API client not initialized, using default priority")
                return 5

            # 获取历史任务数据
            historical_data = await self._get_historical_data(spider_id)

            # 构建提示词
            prompt = f"""
            请分析以下爬虫任务信息，预测其优先级（0-10，数值越大优先级越高）：

            任务信息：
            - 任务ID: {task_id}
            - 爬虫ID: {spider_id}
            - 参数: {json.dumps(parameters, ensure_ascii=False)}

            历史执行数据：
            - 平均执行时间: {historical_data.get('avg_execution_time', 0)}秒
            - 成功率: {historical_data.get('success_rate', 0)}%
            - 失败次数: {historical_data.get('failure_count', 0)}

            请基于以下因素给出优先级评分：
            1. 任务的紧急程度（基于参数判断）
            2. 历史执行效率
            3. 任务复杂度

            请直接返回一个0-10的整数。
            """

            # 调用DeepSeek API
            response = self.client.chat.completions.create(
                model=settings.DEEPSEEK_MODEL,
                messages=[
                    {"role": "system", "content": "你是一个分布式爬虫系统的任务调度专家。"},
                    {"role": "user", "content": prompt}
                ],
                temperature=0.3,
                max_tokens=10,
                stream=False
            )

            content = response.choices[0].message.content.strip()
            try:
                priority = int(content)
                priority = max(0, min(10, priority))  # 确保在0-10范围内
                logger.info(f"DeepSeek predicted priority {priority} for task {task_id}")
                return priority
            except ValueError:
                logger.warning(f"Invalid priority value from DeepSeek: {content}")
                return 5

        except Exception as e:
            logger.error(f"Error predicting task priority: {e}")
            return 5

    async def detect_anomaly(
            self,
            node_id: str,
            metrics: Dict[str, Any]
    ) -> Tuple[bool, str]:
        """检测节点异常"""
        try:
            if not self.client:
                # 简单的阈值检测作为回退策略
                if metrics.get("cpu_usage", 0) > 90:
                    return True, "CPU使用率超过90%"
                if metrics.get("memory_usage", 0) > 90:
                    return True, "内存使用率超过90%"
                return False, ""

            prompt = f"""
            请分析以下节点性能指标，判断是否存在异常：

            节点ID: {node_id}
            指标数据：
            - CPU使用率: {metrics.get('cpu_usage', 0)}%
            - 内存使用率: {metrics.get('memory_usage', 0)}%
            - 负载均衡: {metrics.get('load_average', [])}
            - 磁盘使用率: {metrics.get('disk_usage', {})}

            请判断：
            1. 是否存在异常（true/false）
            2. 如果有异常，请说明异常类型和严重程度

            返回格式：
            {{"is_anomaly": true/false, "message": "异常描述"}}
            """

            # 调用DeepSeek API
            response = self.client.chat.completions.create(
                model=settings.DEEPSEEK_MODEL,
                messages=[
                    {"role": "system", "content": "你是一个系统监控专家，擅长发现性能异常。"},
                    {"role": "user", "content": prompt}
                ],
                temperature=0.1,
                max_tokens=100,
                stream=False
            )

            content = response.choices[0].message.content.strip()
            try:
                # 解析JSON响应
                anomaly_result = json.loads(content)
                is_anomaly = anomaly_result.get("is_anomaly", False)
                message = anomaly_result.get("message", "")

                if is_anomaly:
                    logger.warning(f"Anomaly detected for node {node_id}: {message}")
                    # 存储告警信息到MongoDB
                    await MongoDB.insert_one("alerts", {
                        "node_id": node_id,
                        "type": "performance_anomaly",
                        "message": message,
                        "metrics": metrics,
                        "timestamp": datetime.utcnow()
                    })

                return is_anomaly, message
            except json.JSONDecodeError:
                logger.error(f"Failed to parse DeepSeek response: {content}")
                return False, ""

        except Exception as e:
            logger.error(f"Error detecting anomaly: {e}")
            return False, str(e)

    async def generate_performance_insights(self, time_range: str = "day") -> Dict[str, Any]:
        """生成性能洞察报告"""
        try:
            if not self.client:
                return {
                    "summary": "DeepSeek API未配置",
                    "recommendations": []
                }

            # 收集系统性能数据
            performance_data = await self._collect_performance_data(time_range)

            prompt = f"""
            请分析以下分布式爬虫系统的性能数据，提供优化建议：

            时间范围: {time_range}
            性能数据：
            {json.dumps(performance_data, ensure_ascii=False, indent=2)}

            请提供：
            1. 性能总结（100字以内）
            2. 具体优化建议（3-5条）
            3. 预警事项

            返回JSON格式：
            {{
                "summary": "总结",
                "recommendations": ["建议1", "建议2", "建议3"],
                "warnings": ["预警1", "预警2"]
            }}
            """

            response = self.client.chat.completions.create(
                model=settings.DEEPSEEK_MODEL,
                messages=[
                    {"role": "system", "content": "你是一个分布式系统性能优化专家。"},
                    {"role": "user", "content": prompt}
                ],
                temperature=0.3,
                max_tokens=500,
                stream=False
            )

            content = response.choices[0].message.content.strip()
            try:
                insights = json.loads(content)
                return insights
            except json.JSONDecodeError:
                return {
                    "summary": "无法解析AI响应",
                    "recommendations": [],
                    "warnings": []
                }

        except Exception as e:
            logger.error(f"Error generating insights: {e}")
            return {
                "summary": f"生成洞察时出错: {str(e)}",
                "recommendations": [],
                "warnings": []
            }


# 创建全局实例
ai_optimizer = AIOptimizer()